﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.IO;
using System.Text;
using System.Xml;
using System.Xml.Linq;
using GmaWebService.Interfaces;

namespace GmaWebService.Code.Helper
{
    public class DBLocations
    {
        public string Music;
        public string Pictures;
        public string TvSeries;
        public string MovingPictures;
        public string Shares;
        public string Videos;
    }

    public class Utils
    {
        private static string logDir = AppDomain.CurrentDomain.BaseDirectory + "\\logs";
        private static Dictionary<String, WebBannerPath> CachedWebBannerPaths = null;
        private static String CachedMPLocation;
        private static DBLocations CachedDbLocation;
        private static String CachedUser;
        private static String CachedPassword;

        public static void GetLogin(out string uid, out string pwd, bool overwriteCached)
        {
            if (overwriteCached || CachedUser == null || CachedPassword == null)
            {
                XmlDocument doc = new XmlDocument();
                doc.Load(AppDomain.CurrentDomain.BaseDirectory + "config.xml");
                XmlNode userNode = doc.SelectSingleNode("/appconfig/config/username");
                XmlNode passNode = doc.SelectSingleNode("/appconfig/config/password");
                CachedUser = userNode.InnerText;
                CachedPassword = passNode.InnerText;
            }
            uid = CachedUser;
            pwd = CachedPassword;
        }

        public static bool SetLogin(string uid, string pwd)
        {
            try
            {
                XmlDocument doc = new XmlDocument();
                doc.Load(AppDomain.CurrentDomain.BaseDirectory + "config.xml");
                XmlNode userNode = doc.SelectSingleNode("/appconfig/config/username");
                userNode.InnerText = uid;

                XmlNode passNode = doc.SelectSingleNode("/appconfig/config/password");
                passNode.InnerText = pwd;

                doc.Save(AppDomain.CurrentDomain.BaseDirectory + "config.xml");
                return true;
            }
            catch (Exception ex)
            {
                return false;
            }
        }

        public static String GetMpConfigPath()
        {
            if (CachedMPLocation == null)
            {
                XmlDocument doc = new XmlDocument();
                doc.Load(AppDomain.CurrentDomain.BaseDirectory + "config.xml");
                XmlNode gNode = doc.SelectSingleNode("/appconfig/config/mpconfig");
                string appData = Environment.GetFolderPath(Environment.SpecialFolder.CommonApplicationData);
                CachedMPLocation = gNode.InnerText.Replace("%ProgramData%", appData);
            }

            return CachedMPLocation;
        }

        public static DBLocations GetMPDbLocations()
        {
            if (Utils.CachedDbLocation == null)
            {
                DBLocations dbLocations = new DBLocations();
                XmlDocument doc = new XmlDocument();
                doc.Load(AppDomain.CurrentDomain.BaseDirectory + "config.xml");
                XmlNodeList dbNodes = doc.SelectNodes("/appconfig/mpdatabases/database");
                string appData = Environment.GetFolderPath(Environment.SpecialFolder.CommonApplicationData);

                Log.Debug("Reading database paths");

                foreach (XmlNode node in dbNodes)
                {
                    string name = node.Attributes["name"].Value;

                    // select alternateFilename only when the prefered one is non-existent or has a 0-byte size and the alternate one
                    // exists and is bigger then 0 bytes
                    string value = node.Attributes["filename"].Value.Replace("%ProgramData%", appData);
                    string alternateValue = node.Attributes["alternateFilename"] != null ?
                        node.Attributes["alternateFilename"].Value.Replace("%ProgramData%", appData) : 
                        null;
                    if (alternateValue != null && 
                        (!File.Exists(value) || new FileInfo(value).Length == 0) && 
                        (File.Exists(alternateValue) && new FileInfo(alternateValue).Length > 0))
                        value = alternateValue;

                    Log.Debug(name + ": " + value);
                    switch (name)
                    {
                        case "music":
                            dbLocations.Music = value.Replace("%ProgramData%", appData);
                            break;
                        case "pictures":
                            dbLocations.Pictures = value.Replace("%ProgramData%", appData);
                            break;
                        case "tvseries":
                            dbLocations.TvSeries = value.Replace("%ProgramData%", appData);
                            break;
                        case "movingpictures":
                            dbLocations.MovingPictures = value.Replace("%ProgramData%", appData);
                            break;
                        case "shares":
                            dbLocations.Shares = value.Replace("%ProgramData%", appData);
                            break;
                        case "videos":
                            dbLocations.Videos = value.Replace("%ProgramData%", appData);
                            break;
                    }
                }
                CachedDbLocation = dbLocations;
            }
            return CachedDbLocation;
        }

        public static void ChangeDbLocation(String _db, String _newPath)
        {
            XmlDocument doc = new XmlDocument();
            doc.Load(AppDomain.CurrentDomain.BaseDirectory + "config.xml");
            XmlNodeList dbNodes = doc.SelectNodes("/appconfig/mpdatabases/database");

            Log.Debug("Reading database paths");

            foreach (XmlNode node in dbNodes)
            {
                String name = node.Attributes["name"].Value;

                if (name.Equals(_db))
                {
                    node.Attributes["filename"].Value = _newPath;
                }
            }

            doc.Save(AppDomain.CurrentDomain.BaseDirectory + "config.xml");
        }


        public static Dictionary<String, WebBannerPath> GetWebBannerPaths()
        {
            if (Utils.CachedWebBannerPaths == null)
            {
                XmlDocument doc = new XmlDocument();
                doc.Load(AppDomain.CurrentDomain.BaseDirectory + "config.xml");
                XmlNodeList dbNodes = doc.SelectNodes("/appconfig/thumbpaths/thumb");
                Dictionary<String, WebBannerPath> retList = new Dictionary<String, WebBannerPath>();
                string cappdata = Environment.GetFolderPath(Environment.SpecialFolder.CommonApplicationData);
                foreach (XmlNode node in dbNodes)
                {
                    retList.Add(node.Attributes["name"].Value, new WebBannerPath(node.Attributes["name"].Value,
                                                                              node.Attributes["path"].Value.Replace("%ProgramData%", cappdata),
                                                                              node.Attributes["virtualpath"].Value));
                }
                CachedWebBannerPaths = retList;
                return retList;
            }
            else
            {
                return CachedWebBannerPaths;
            }
        }


        public static String[] SplitString(String _stringToSplit)
        {
            if (_stringToSplit != null)
            {
                _stringToSplit = _stringToSplit.Trim(new char[] { '|', ' ' });
                return _stringToSplit.Split(new string[] { "|" }, StringSplitOptions.RemoveEmptyEntries);
            }
            else
            {
                return null;
            }
        }
        public static string ClearString(String _stringToClean)
        {
            return _stringToClean.Substring(2, (_stringToClean.Length - 5));
        }


        public static string GetCoverArtName(string strFolder, string strFileName)
        {
            if (string.IsNullOrEmpty(strFolder) || string.IsNullOrEmpty(strFileName))
                return string.Empty;

            return string.Format(@"{0}\{1}{2}", strFolder, Utils.MakeFileName(strFileName), ".jpg");
        }

        public static string GetLargeCoverArtName(string strFolder, string strFileName)
        {
            if (string.IsNullOrEmpty(strFolder) || string.IsNullOrEmpty(strFileName))
                return string.Empty;

            return Utils.GetCoverArtName(strFolder, strFileName + "L");
        }

        public static string GetLargeAlbumCover(string artistName, string albumName)
        {
            if (string.IsNullOrEmpty(artistName) || string.IsNullOrEmpty(albumName))
                return string.Empty;

            artistName = artistName.Trim(new char[] { '|', ' ' });
            albumName = albumName.Replace(":", "_");
            String musicThumbPath = Utils.GetWebBannerPaths()["music"].Path;

            return Utils.GetCoverArtName(Path.Combine(musicThumbPath, "Albums"), artistName + "-" + albumName + "L");
        }

        public static string MakeFileName(string strText)
        {
            if (strText == null) return string.Empty;
            if (strText.Length == 0) return string.Empty;

            string strFName = strText.Replace(':', '_');
            strFName = strFName.Replace('/', '_');
            strFName = strFName.Replace('\\', '_');
            strFName = strFName.Replace('*', '_');
            strFName = strFName.Replace('?', '_');
            strFName = strFName.Replace('\"', '_');
            strFName = strFName.Replace('<', '_');
            strFName = strFName.Replace('>', '_');
            strFName = strFName.Replace('|', '_');

            bool unclean = true;
            char[] invalids = Path.GetInvalidFileNameChars();
            while (unclean)
            {
                unclean = false;

                char[] filechars = strFName.ToCharArray();

                foreach (char c in filechars)
                {
                    if (!unclean)
                        foreach (char i in invalids)
                        {
                            if (c == i)
                            {
                                unclean = true;
                                //Log.Warn("Utils: *** File name {1} still contains invalid chars - {0}", Convert.ToString(c), strFName);
                                strFName = strFName.Replace(c, '_');
                                break;
                            }
                        }
                }
            }
            return strFName;
        }



    }
}